//
//  PhoneLoginViewModel.swift
//  User
//
//  Created by ET|冰琳 on 2017/1/9.
//  Copyright © 2017年 IB. All rights reserved.
//

import UIKit
import ReactiveSwift
import ReactiveCocoa
import enum Result.NoError


public enum PhonePwdLoginError: Error {
    case phoneInvalide
    case passwordInvalide
    case error(msg: String)
}


/// 手机号密码登录
/// login with phone and password
open class PhonePwdLoginViewModel<Service: PhonePwdLoginService>: NSObject {


    open let phone    = MutableProperty<String?>(nil)
    open let password = MutableProperty<String?>(nil)

    open let phoneValid     = MutableProperty(false)
    open let passwordValid  = MutableProperty(false)
    
    open var phoneValidator: Validator?
    open var passwordValidator: Validator?
    
    private let service: Service
    
    open var loginAction: Action<(), Service.PhonePwdLoginResult, PhonePwdLoginError>!
    
    /// - Parameter service: PhonePwdLoginService
    public init(service: Service){
        self.service = service
        super.init()
        self.calculate()
    }
    
    private func calculate(){
        
        phoneValid <~ phone.signal.map{
            let validator = self.phoneValidator ?? PhoneValidator()
            print(validator)
            return validator.validate(txt: $0)
        }
        
        passwordValid <~ password.signal.map{
            let validator = self.passwordValidator ?? DefaultValidator()
            return validator.validate(txt: $0)
        }
        
        // action
        loginAction = Action { return self.login() }
    }
    
    public func login() -> SignalProducer<Service.PhonePwdLoginResult, PhonePwdLoginError> {
        
        guard self.phoneValid.value else {
            return SignalProducer(error: .phoneInvalide)
        }
        
        guard self.passwordValid.value else {
            return SignalProducer(error: .passwordInvalide)
        }
        
        return self.service.loginWith(phone: self.phone.value, pwd: self.password.value).flatMapError({ (err) -> SignalProducer<Service.PhonePwdLoginResult, PhonePwdLoginError> in
            return SignalProducer(error: .error(msg: err.localizedDescription))
        })
    }
}
